class GameEntityTags implements HashSet<String> {
  final GameEntity entity;
  final HashSet<String> s;
  
  GameEntityTags(GameEntity e) : entity = e, s = new HashSet<String>() { }
  GameEntityTags.from(GameEntity e, Set other) : entity = e, s = new HashSet<String>.from(other) {
    final w = world;
    s.forEach((v) => w._onTagAdded(entity, v));
  }
  
  Iterator<String> iterator() => s.iterator();
  bool every(bool f(String element)) => s.every(f);
  Collection<String> filter(bool f(String element)) => s.filter(f);
  void forEach(void f(String element)) => s.forEach(f);
  bool isEmpty() => s.isEmpty();
  int get length() => s.length;
  Collection<String> map(f(String element)) => s.map(f);
  bool some(bool f(String element)) => s.some(f);
  void add(String value) {
    if (s.contains(value) == false) {
      s.add(value);
      world._onTagAdded(entity, value);
    }
  }
  void addAll(Collection<String> collection) {
    collection.forEach((v) {
      if (s.contains(v) == false) {
        world._onTagAdded(entity, v);
        s.add(v);
      }
    });
  }
  void clear() {
    s.forEach((v) => world._onTagRemoved(entity, v));
    s.clear();
  }
  bool contains(String value) => s.contains(value);
  bool containsAll(Collection<String> collection) => s.containsAll(collection);
  Set<String> intersection(Collection<String> other) => s.intersection(other);
  bool isSubsetOf(Collection<String> collection) => s.isSubsetOf(collection);
  bool remove(String value) {
    if (s.remove(value))
      world._onTagRemoved(entity, value);
  }
  void removeAll(Collection<String> collection) {
    collection.forEach((v) {
      if (s.remove(v))
        world._onTagRemoved(entity, v);
    });
  }
}